/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef GEOFENCE_MSDP_RDB_H
#define GEOFENCE_MSDP_RDB_H

#include <string>
#include <memory>
#include <vector>
#include <thread>
#include <map>
#include <errors.h>
#include "rdb_store.h"
#include "rdb_helper.h"
#include "rdb_open_callback.h"
#include "rdb_store_config.h"
#include "values_bucket.h"
#include "result_set.h"
#include "geofence_data_utils.h"
#include "igeofence_impl_interface.h"


namespace OHOS {
namespace Msdp {
class GeofenceRdb {
public:
    using CallbackLocationImpl = std::function<int32_t(GeofenceDataUtils::LocationData&)>;
    using CallbackCloudImpl = std::function<int32_t(GeofenceDataUtils::CloudData&)>;
    enum EventType {
        EVENT_UEVENT_FD,
        EVENT_TIMER_FD,
    };

    bool Init();
    void InitRdbStore();
    void SetTimerInterval(int interval);
    void InitTimer();
    void TimerCallback();
    int RegisterTimerCallback(const int fd, const EventType et);
    void StartThread();
    void LoopingThreadEntry();
    ErrCode RegisterLocation(CallbackLocationImpl callback);
    ErrCode UnregisterLocation() const;
    ErrCode RegisterCloud(const GeofenceDataUtils::PoiOptions& poiOptions, CallbackCloudImpl callback);
    ErrCode UnregisterCloud() const;
    ErrCode NotifyMsdpLocationImpl(GeofenceDataUtils::LocationData& locationData);
    ErrCode NotifyMsdpCloudImpl(GeofenceDataUtils::CloudData& fenceData);
    std::vector<double> JudgeRdbLocationData(int timeStamp, std::vector<double> location);
    bool RecordCloudCacheData(GeofenceDataUtils::PoiOptions& poiOptions, GeofenceDataUtils::CloudData& cloudData);
    int TrigerLocationDatabaseObserver();
    int TrigerCloudDatabaseObserver();
    GeofenceDataUtils::CloudData GetCloudCacheData(const GeofenceDataUtils::PoiOptions& poiOptions);
    int32_t SetTrack(std::string timeStamp, int32_t screenState, std::string cell);
    ErrCode Enable();
    ErrCode Disable();

private:
    using Callback = std::function<void(GeofenceRdb*)>;
    CallbackLocationImpl callbacksLocationImpl_;
    GeofenceDataUtils::PoiOptions poiOptions_;
    CallbackCloudImpl callbacksCloudImpl_;
    std::map<int32_t, Callback> callbacks_;
    std::shared_ptr<NativeRdb::RdbStore> store_;
    bool notifyLocationFlag_ = false;
    int timerInterval_ = -1;
    int32_t timerFd_ = -1;
    int32_t epFd_ = -1;
    std::map<int, std::vector<double>> rdbDataMap_;
};

class InsertOpenCallback : public NativeRdb::RdbOpenCallback {
public:
    int OnCreate(NativeRdb::RdbStore &rdbStore) override;
    int OnUpgrade(NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override;
};
}
}
#endif // GEOFENCE_MSDP_RDB_H

